package com.slashvision.im.chat

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.*
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.core.app.NotificationManagerCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.fragment.findNavController
import androidx.navigation.navArgument
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.slashvision.im.ContextUtil
import com.slashvision.im.R
import com.slashvision.im.SLog
import com.slashvision.im.databinding.FragmentComposeBinding
import com.slashvision.im.eventbus.Bus
import com.slashvision.im.toastShort
import com.slashvision.im.tool.FileUtil
import com.slashvision.im.tool.StorgeUtil
import com.slashvision.im.tool.TimeUtil
import com.slashvision.stylist.common.eventbus.BusKey
import io.openim.android.sdk.OpenIMClient
import io.openim.android.sdk.models.Message
import java.io.File

/**
 * author : lizhenxin
 *  date  : 2021/10/8
 *  desc  : 只负责处理数据
 */
const val KEY_ID = "_KEY_ID_"
const val KEY_NAME = "_KEY_NAME_"
const val KEY_PATH = "_KEY_PATH_"


class ChatFragment : Fragment() {

    private var lastSendTime = 0L
    private var lastRecTime = 0L

    private val chatVM by activityViewModels<ChatViewModel>()



    private lateinit var captureFilePath: String
    private lateinit var pictureLauncher: ActivityResultLauncher<Uri>
    private lateinit var videoLauncher: ActivityResultLauncher<Uri>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initLauncher()
    }

    private lateinit var binding: FragmentComposeBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentComposeBinding.inflate(inflater, container, false)
        return binding.root
    }

    @ExperimentalComposeUiApi
    @ExperimentalPermissionsApi
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        beforeCompose()

        binding.baseComposeView.setContent {
            BaseComposeView()
        }
    }


    fun beforeCompose() {
//        super.beforeCompose()


        /*vm.msgList.observe(viewLifecycleOwner) {
            SLog.d(TAG_IM, "和${mFriendId}服务器消息数量：${it.size}")
            uiState.setMsgList(it)
        }
        vm.getMsgList(mFriendId)*/

        Bus.with<Message>(BusKey.RECEIVE_MESSAGE).register(this) {
            val current = System.currentTimeMillis()
            if (current - lastRecTime > 10) {
                SLog.d(TAG_IM, "ChatFragment收到转发消息：${it.content}")
                chatVM.apply {
                    currentUIState.addMsg(it)
                    setConvRead()
                    setMsgRead(listOf(it.clientMsgID))
                }

                /*uiState.addMsg(it)
                vm.setConvRead(mFriendId)
                vm.setMsgRead(mFriendId, listOf(it.clientMsgID))*/
            }
            lastRecTime = current
        }


        Bus.with<String>(BusKey.TAKE_PHOTO).register(this) {
            val currentTime = System.currentTimeMillis()
            if (currentTime - lastSendTime > 10) {
                takePicture()
            }
            lastSendTime = currentTime
        }
        Bus.with<String>(BusKey.TAKE_VIDEO).register(this) {
            val currentTime = System.currentTimeMillis()
            if (currentTime - lastSendTime > 10) {
                takeVideo()
            }
            lastSendTime = currentTime
        }

        NotificationManagerCompat.from(requireContext())
            .getNotificationChannel(/*mFriendId*/chatVM.getFriendId())?.let {
                NotificationManagerCompat.from(requireContext()).cancelAll()
            }
    }

    @ExperimentalPermissionsApi
    @ExperimentalComposeUiApi
    @Composable
    fun BaseComposeView() {
        val navController = rememberNavController()
        NavHost(navController = navController, startDestination = ROUTE_CHAT_UI) {
            composable(ROUTE_CHAT_UI) { PageChat(vm = chatVM, navController = navController) }
            composable("${ROUTE_IMAGE_PREVIEW}?isNet={isNet}&path={path}", arguments = listOf(
                navArgument("isNet") {
                    type = NavType.BoolType
                    defaultValue = true
                },
                navArgument("path") { type = NavType.StringType }
            )) {
                val isNet = it.arguments?.getBoolean("isNet", true)
                val path = it.arguments?.getString("path")
                path?.let {
                    PageImagePreview(
                        isNetImage = isNet?:true,
                        path = path,
                        navController = navController
                    )
                }
            }
        }
    }


    private fun initLauncher() {
        pictureLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) {
            ContextUtil.getContext().toastShort(if (it) "拍摄成功" else "拍摄失败")
            if (it) {
                SLog.d(TAG_IM, "图片保存路径：${captureFilePath}")
                val msg =
                    OpenIMClient.getInstance().messageManager.createImageMessageFromFullPath(
                        captureFilePath
                    )
                sendMessage(msg)
            } else {
                File(captureFilePath).takeIf { it.exists() }?.delete()
            }
        }

        videoLauncher = registerForActivityResult(TimeLimitVideoContract) {
            ContextUtil.getContext().toastShort(if (it) "录制成功" else "录制失败")
            if (it) {
                SLog.d(TAG_IM, "视频保存路径：${captureFilePath}")
                FileUtil.getVideoInfo(captureFilePath)?.let { info ->
                    val msg =
                        OpenIMClient.getInstance().messageManager.createVideoMessageFromFullPath(
                            info.videoPath,
                            info.videoType,
                            info.duration,
                            info.snapshotPath
                        )
                    sendMessage(msg)
                }
            } else {
                File(captureFilePath).takeIf { it.exists() }?.delete()
            }
        }
    }


    private fun takePicture() {
        val f = File(StorgeUtil.pictureCacheDir, "${TimeUtil.NOW()}.jpg")
        if (f.exists()) {
            f.delete()
        }
        f.createNewFile()
        captureFilePath = f.absolutePath
        val uri = StorgeUtil.getUriFromFile(f)
        SLog.d(TAG_IM, "path: ${f.absolutePath},  uri: ${uri.toString()}")

        pictureLauncher.launch(uri)
    }


    private fun takeVideo() {
        val f = File(StorgeUtil.videoCacheDir, "${TimeUtil.NOW()}.mp4")
        if (f.exists()) {
            f.delete()
        }
        f.createNewFile()
        captureFilePath = f.absolutePath
        val uri = StorgeUtil.getUriFromFile(f)
        SLog.d(TAG_IM, "path: ${f.absolutePath},  uri: ${uri.toString()}")
        videoLauncher.launch(uri)
    }

    private fun sendMessage(msg: Message) {
        chatVM.sendMessage(msg)
        chatVM.currentUIState.addMsg(msg)
//        uiState.addMsg(msg)
    }

    private val TimeLimitVideoContract = object : ActivityResultContract<Uri, Boolean>() {
/*        override fun createIntent(context: Context, input: Uri?): Intent = input?.let {

        } ?: throw InputMismatchException()*/

        override fun parseResult(resultCode: Int, intent: Intent?) =
            resultCode == Activity.RESULT_OK

        override fun createIntent(context: Context, input: Uri): Intent {
            return Intent(MediaStore.ACTION_VIDEO_CAPTURE).apply {
                //储存地址
                this.putExtra(MediaStore.EXTRA_OUTPUT, input)
                //用于控制录制视频的质量；0——低质量；1——高质量
                this.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
                //允许记录的最长时间(以 秒 为单位)  例如：限制为60S
                this.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10)
                //允许的最大大小(以 B 为单位)  例如：限制大小为100M
//        this.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024L * 1024 * 100)
            }
        }
    }


}